package sms

import (
	"encoding/json"
	"errors"
	"strconv"

	"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
)

const (
	ALIBABA_SMS_APPKEY    = "LTAIsweOqqtC66yA"
	ALIBABA_SMS_APPSECRET = "8Xht4zmiHL0Xzy3N8CZsyoq1iWN9SO"
	ALIBABA_SMS_SIGN      = "东南街道"
)

type AliSms struct {
	appkey    string
	secretkey string
	regionId  string
	sign      string
}

type Message struct {
	Message   string
	RequestId string
	BizId     string
	Code      string
}

func NewAliSms(appkey, secret string) *AliSms {
	return &AliSms{
		appkey:    appkey,
		secretkey: secret,
		sign:      ALIBABA_SMS_SIGN,
	}
}

func newAliSms() *AliSms {
	return NewAliSms(ALIBABA_SMS_APPKEY, ALIBABA_SMS_APPSECRET)
}

func (a *AliSms) SetSign(sign string) {
	a.sign = sign
}

func (a *AliSms) SetRegion(region string) {
	a.regionId = region
}

// 发送短信
func (a *AliSms) Send(mobile string, content SmsContent) error {
	param, err := json.Marshal(content.Encode())
	if err != nil {
		return err
	}
	client, err := sdk.NewClientWithAccessKey(a.regionId, a.appkey, a.secretkey)
	if err != nil {
		return err
	}

	request := requests.NewCommonRequest()                 // 构造一个公共请求
	request.Method = "POST"                                // 设置请求方式
	request.Product = "Ecs"                                // 指定产品
	request.Scheme = "https"                               // https | http
	request.Domain = "dysmsapi.aliyuncs.com"               // 指定域名则不会寻址，如认证方式为 Bearer Token 的服务则需要指定
	request.Version = "2017-05-25"                         // 指定产品版本
	request.ApiName = "SendSms"                            // 指定接口名
	request.QueryParams["RegionId"] = "cn-hangzhou"        // 地区
	request.QueryParams["PhoneNumbers"] = mobile           //手机号
	request.QueryParams["SignName"] = a.sign               //阿里云验证过的项目名 自己设置
	request.QueryParams["TemplateCode"] = content.GetTpl() //阿里云的短信模板号 自己设置
	request.QueryParams["TemplateParam"] = string(param)   //短信模板中的验证码内容 自己生成

	response, err := client.ProcessCommonRequest(request)
	if err != nil {
		return err
	}
	//阿里云返回的json信息对应的类
	var message Message
	//记得判断错误信息
	if err = json.Unmarshal(response.GetHttpContentBytes(), &message); err != nil {
		return err
	}
	if message.Message != "OK" {
		return errors.New("短信发送失败")
	}
	return nil
}

// 群发短信
func (a *AliSms) SendBatch(mobiles []string, tpl string) error {
	client, err := sdk.NewClientWithAccessKey(a.regionId, a.appkey, a.secretkey)
	if err != nil {
		return err
	}

	mobilesJson, _ := json.Marshal(mobiles)
	signs := make([]string, 0, len(mobiles))
	for i := 0; i < len(mobiles); i++ {
		signs = append(signs, a.sign)
	}
	signJson, _ := json.Marshal(signs)

	request := requests.NewCommonRequest()                       // 构造一个公共请求
	request.Method = "POST"                                      // 设置请求方式
	request.Product = "Ecs"                                      // 指定产品
	request.Scheme = "https"                                     // https | http
	request.Domain = "dysmsapi.aliyuncs.com"                     // 指定域名则不会寻址，如认证方式为 Bearer Token 的服务则需要指定
	request.Version = "2017-05-25"                               // 指定产品版本
	request.ApiName = "SendBatchSms"                             // 指定接口名
	request.QueryParams["RegionId"] = "cn-hangzhou"              // 地区
	request.QueryParams["PhoneNumberJson"] = string(mobilesJson) //手机号
	request.QueryParams["SignNameJson"] = string(signJson)       //阿里云验证过的项目名 自己设置
	request.QueryParams["TemplateCode"] = tpl                    //阿里云的短信模板号 自己设置
	//request.QueryParams["TemplateParam"] = string(param)      //短信模板中的验证码内容 自己生成

	response, err := client.ProcessCommonRequest(request)
	if err != nil {
		return err
	}
	//阿里云返回的json信息对应的类
	var message Message
	//记得判断错误信息
	if err = json.Unmarshal(response.GetHttpContentBytes(), &message); err != nil {
		return err
	}

	if message.Message != "OK" {
		return errors.New("短信发送失败")
	}
	return nil
}

type CommitTplMessage struct {
	Message      string
	RequestId    string
	Code         string
	TemplateCode string
}

// 提交短信模板
func (a *AliSms) CommitTemplate(tpl *SmsTemplate) error {
	if tpl.Code != "" || tpl.Status != 0 {
		return errors.New("该模板已存在，请不要重复提交")
	}

	client, err := sdk.NewClientWithAccessKey(a.regionId, a.appkey, a.secretkey)
	if err != nil {
		return err
	}

	request := requests.NewCommonRequest()                       // 构造一个公共请求
	request.Method = "POST"                                      // 设置请求方式
	request.Product = "Ecs"                                      // 指定产品
	request.Scheme = "https"                                     // https | http
	request.Domain = "dysmsapi.aliyuncs.com"                     // 指定域名则不会寻址，如认证方式为 Bearer Token 的服务则需要指定
	request.Version = "2017-05-25"                               // 指定产品版本
	request.ApiName = "AddSmsTemplate"                           // 指定接口名
	request.QueryParams["RegionId"] = "cn-hangzhou"              // 地区
	request.QueryParams["TemplateType"] = strconv.Itoa(tpl.Type) //模板类型
	request.QueryParams["TemplateName"] = tpl.Name
	request.QueryParams["TemplateContent"] = tpl.Content
	request.QueryParams["Remark"] = tpl.Remark
	//request.QueryParams["TemplateParam"] = string(param)      //短信模板中的验证码内容 自己生成

	response, err := client.ProcessCommonRequest(request)
	if err != nil {
		return err
	}
	//阿里云返回的json信息对应的类
	var message CommitTplMessage
	//记得判断错误信息
	if err = json.Unmarshal(response.GetHttpContentBytes(), &message); err != nil {
		return err
	}

	if message.Code != "OK" {
		return errors.New("模板提交失败")
	}

	tpl.Code = message.TemplateCode
	return nil
}

type QueryTplMsg struct {
	Code            string
	Message         string
	RequestId       string
	TemplateName    string
	TemplateCode    string
	TemplateType    int
	TemplateContent string
	TemplateStatus  int
	CreateDate      string
	Reason          string
}

// 检查短信模板是否通过审核
func (a *AliSms) CheckTemplate(tpl *SmsTemplate) error {
	client, err := sdk.NewClientWithAccessKey(a.regionId, a.appkey, a.secretkey)
	if err != nil {
		return err
	}

	request := requests.NewCommonRequest()          // 构造一个公共请求
	request.Method = "POST"                         // 设置请求方式
	request.Product = "Ecs"                         // 指定产品
	request.Scheme = "https"                        // https | http
	request.Domain = "dysmsapi.aliyuncs.com"        // 指定域名则不会寻址，如认证方式为 Bearer Token 的服务则需要指定
	request.Version = "2017-05-25"                  // 指定产品版本
	request.ApiName = "QuerySmsTemplate"            // 指定接口名
	request.QueryParams["RegionId"] = "cn-hangzhou" // 地区
	request.QueryParams["TemplateCode"] = tpl.Code

	response, err := client.ProcessCommonRequest(request)
	if err != nil {
		return err
	}
	//阿里云返回的json信息对应的类
	var message QueryTplMsg
	//记得判断错误信息
	if err = json.Unmarshal(response.GetHttpContentBytes(), &message); err != nil {
		return err
	}

	if message.Code != "OK" {
		return errors.New("获取审核结果失败")
	}

	switch message.TemplateStatus {
	case 0:
		tpl.Status = 0
	case 1:
		tpl.Status = 1
	case 2:
		tpl.Status = 2
	case 10:
		tpl.Status = 2
	}

	return nil
}
